Skip to content

Allow users to specify distribution and component when modifying content - #1492

Open
daviddavis wants to merge 1 commit into
pulp:mainfrom
daviddavis:repository-modify-structure
Open

Allow users to specify distribution and component when modifying content#1492
daviddavis wants to merge 1 commit into
pulp:mainfrom
daviddavis:repository-modify-structure

Conversation

@daviddavis

@daviddavis daviddavis commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Allow repositories/deb/apt/{pulp_id}/modify/ requests to add/remove packages using optional distribution and component parameters. The task will create or remove matching release structure content while preserving package-only behavior when both parameters are omitted.

fixes #1491

@daviddavis daviddavis changed the title Add repository modify structure metadata Allow users to specify distribution and component when modifying content Jul 29, 2026
@daviddavis
daviddavis marked this pull request as draft July 29, 2026 15:37
@daviddavis
daviddavis force-pushed the repository-modify-structure branch 4 times, most recently from 77c51ac to 80bb31b Compare July 29, 2026 18:49
@daviddavis
daviddavis marked this pull request as ready for review July 29, 2026 18:58
@daviddavis
daviddavis force-pushed the repository-modify-structure branch 4 times, most recently from 72f3350 to 251cab2 Compare July 30, 2026 12:13
@daviddavis
daviddavis marked this pull request as draft July 30, 2026 12:13
@daviddavis
daviddavis force-pushed the repository-modify-structure branch from 251cab2 to 9f78c10 Compare July 30, 2026 18:10
@daviddavis
daviddavis marked this pull request as ready for review July 30, 2026 19:36
@daviddavis
daviddavis force-pushed the repository-modify-structure branch from 9f78c10 to ca95206 Compare July 30, 2026 19:40
@quba42 quba42 added the .feature CHANGES/<issue_number>.feature label Aug 24, 2026
@quba42

quba42 commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

First of all: I really appreciate this change! I started by testing some workflows using this, against my own assumptions and expectations. Overall the current state makes very reasonable design choices. It appears to work well (though I have not yet tested the content removal workflows 😉)

That being said, on the details, there are several design choices I would like to have some (open ended) discussion on. To avoid this turning to chaotic, I am going to avoid GitHub's review feature for now, and will instead open a thread for each independent thing I would like to discuss. I may need a bit of time to add each thread below.

Comment thread CHANGES/1491.feature
Comment thread pulp_deb/app/tasks/signing.py Outdated
Comment thread pulp_deb/app/tasks/signing.py Outdated
Comment on lines +41 to +53
# A request that only names a component is scoped to the default distribution.
distribution = data.get("distribution") or PACKAGE_UPLOAD_DEFAULT_DISTRIBUTION
releases = Release.objects.filter(distribution=distribution)
repository = self.context.get("repository")
repository_version = data.get("base_version") or (
repository.latest_version() if repository else None
)
added = releases.filter(pk__in=data.get("add_content_units", [])).exists()
present = repository_version and releases.filter(pk__in=repository_version.content).exists()
if not (added or present):
raise DRFValidationError(
{"distribution": _("This distribution has no Release in the repository.")}
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consider this to be the most important design choice of this new feature.
It is the thing users who want to use the new fields are most likely to trip over.

From the point of view of the publish code, we don't need to demand there be a Release object to go with the distribution we are targeting. If there is a ReleaseComponent with distribution="my-distribution", but no Releae with distribution="my-distribution", then the publish code will simply invent a default Release object: https://github.com/pulp/pulp_deb/blob/main/pulp_deb/app/tasks/publishing.py#L219

So, we could drop this requirement entirely. If users provide a distribution and/or component value to the modify endpoint, we would simply create the repo structure that these values imply. If they don't like the default values in the Release file, they could still add a custom Release object later.

However, I wonder if it makes sense to have some barrier against users accidentally messing up their repositories, for example because they have a typo in the distribution they supplied. (I suppose if you do mess it up, then the weird result would at least be contained within its own repo version which you could simply delete again).

With the current design there is a barrier against providing a weird distribution, but there is no barrier against providing a weird component. So another version of this validation might be to demand you either add or already have present a ReleaseComponent that matches both the distribution and the release you are targeting.

So I currently see three options here:

  1. Validation based on presence or addition of Release object (current state of the PR)
  2. No validation at all (you simply get what you ask for, even if what you asked for contains obvious errors).
  3. Validation based on presence or addition of a ReleaseComponent (I am not going to let you add the packages to a repo structure that is not already part of the repo, and that you have not explicitly asked me to add).

Opinions?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typos would be my biggest concern. If someone misspells something, it is not an easy action to undo. In our system, creating a release or component is an explicit step the user must perform so I think it helps to minimize this risk.

That said, we are validating that the release and the component exist before we hand the modify request off to Pulp so we don't have a strong opinion which option we decide here. In fact, I see good arguments for each.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this one internally and we came out leaning towards "no validation", that is you get what you asked for whether that is what you wanted or not.

For number 3. we decided this would again ask users to interact with the plumbing we are trying to insulate them from.

For number 1. (validation based on Release, current state) we decided we should not demand the presence of Release objects given they are not technically required.

Overall my thinking is: If we want to move towards making use of this feature mandatory, then it must be as easy to use as possible. And throwing validation errors demanding certain things should already be in the repo (or must be provided with the modify) makes it harder to use/discourages usage.

I do still worry about typos being a very bad experience here. (Also providing one of distribution/component and not understanding about the implication that this causes the other to default to our default value). The thing that mitigates my concern is that the resulting chaos would be contained within its own repository version. Of course, if users start building further versions on top of the broken one before they realize their error, it can quickly become hard to recover from. I would hope that for most users this would only be an issue when they first experiment with the plugin, and will then quickly learn...

On the whole I still lean towards making the feature easy to use even if this increases the risk of typos resulting in bad outcomes.

@quba42

quba42 commented Aug 26, 2026

Copy link
Copy Markdown
Collaborator

I am going to leave it at that for now. Note that while I may have produced a lot of text, all of the above are posed as open questions. Disagreeing with any implied changes is perfectly fine. If, after some discussion, we conclude we want to stay with the current design that is a perfectly reasonable outcome.

@daviddavis
daviddavis force-pushed the repository-modify-structure branch 2 times, most recently from 07bd0b6 to f318641 Compare August 28, 2026 12:44
@daviddavis

Copy link
Copy Markdown
Contributor Author

@quba42 I think I've addressed everything. Please let me know what you think.

@balasankarc

Copy link
Copy Markdown

cc @stanhu FYI as you worked on pulp/pulp-cli-deb#260

@daviddavis

daviddavis commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

@balasankarc @stanhu reading pulp/pulp-cli-deb#245, it seems like maybe the field here should be distributions instead of distribution? So that way you can add a package to multiple distributions when you add it to the repo. I don't think that would be too difficult to do.

@quba42 quba42 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found two more minor changes I would like to see.

With those final changes I am happy to merge. I have manually tested many workflows I wanted to see (like adding a package already in the repo to another ReleaseComponent, removing packages from just one ReleaseComponent. Removing a package from the repo and all ReleaseComponents (by not providing the new params). Adding multiple packages. Re-running a command that results in a noop because everything is already present, etc.

I also looked over the new automatic tests which provide good coverage for those same workflows I most wanted to test manually. 👍

Comment thread pulp_deb/app/serializers/repository_serializers.py Outdated
Comment thread pulp_deb/app/tasks/signing.py Outdated
Comment on lines +48 to +51
Removing a (source) package also requires removing its PackageReleaseComponent /
SourcePackageReleaseComponent links. When a distribution/component is given, the removal is
scoped to that component: a package is only removed from the repository if the scope held its
last relationship, so packages linked elsewhere or not linked at all are kept.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This describes my preferred behavior, and I tested this is in fact what happens. Also tested that removing a package without providing distribution and/or component, removes it and all PRCs referencing it from the repo as in the past.

So all things removal look good to me. 👍

@quba42

quba42 commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

One thing I did not test is what happens when you provide both add_content_units and remove_content units and a component or distribution in a single call. From the way the individual calls work and how the code is structured I am pretty confident it will simply be the conjunction of the two individual calls. I am not sure how important this corner case is. I would expect the vast majority of users to split that request up into two calls, just because the request "add these packages to this ReleaseComponent and also remove these other packages from the same ReleaseComponent at the same time" is conceptually pretty weird. 😄

If you end up requesting the same package be added and also removed in the same call, I don't particularly care what happens since such a clearly contradictory request arguably should result in undefined behavior.

@daviddavis

Copy link
Copy Markdown
Contributor Author

I agree that most users will probably add/remove in a single call. It should handle requests to both add and remove content in a single call though by both adding and removing the packages that the user requests to add and remove.

The one edge case you alluded to where there is an overlap of content is not obvious for users though without looking at the code (I believe that the answer is that the content gets added). I agree though that we shouldn't worry about it since it's obviously unusual and contradictory.

@daviddavis
daviddavis force-pushed the repository-modify-structure branch 2 times, most recently from 38f6b71 to a943aaf Compare September 1, 2026 18:43
Allow repositories/deb/apt/{pulp_id}/modify/ requests to add/remove
packages using optional distribution and component parameters. The task
will create or remove matching release structure content while
preserving package-only behavior when both parameters are omitted.

fixes pulp#1491

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: c96b6a1b-7b9e-4fea-ada4-73292625182f
@daviddavis
daviddavis force-pushed the repository-modify-structure branch from a943aaf to 75486ca Compare September 1, 2026 18:56
@daviddavis

Copy link
Copy Markdown
Contributor Author

I went ahead and added a new functional test (test_add_and_remove_packages_in_same_request) to test adding/removing packages a single request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.feature CHANGES/<issue_number>.feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow users to supply distribution and component when modifying repo contents

3 participants